04. 定义任务
定义任务
正如之前提到的,我们已经在
tasks/takeoff.py
中为你定义了起飞任务。你可以看看该任务,了解任务对象如何充当 ROS 和智能体代码之间的媒介。
-
__init__():定义特定于任务的参数,包括状态(观察结果)空间和动作空间。 -
reset():在每个阶段开始时初始化状态,将无人机扔到地面上。 -
update():当出现新的状态时,ROS 会定期调用该方法。它在每个时间步将该状态传递给智能体,以及奖励值,获得一个动作,然后将该动作传回 ROS。
(
ROS 然后将该动作发送给模拟环境,并获得下个状态以提供给
update()
。
)
任务的奖励函数定义如下:
reward = -min(abs(self.target_z - pose.position.z), 20.0)
即
reward = 0
表示匹配目标
z
,离得越远,则为负数,低达
-20
。如果四轴无人机达到目标高度,则获得额外的奖励,如果时间超时,则获得额外的惩罚。
运行任务
运行以下命令以使用默认参数启动 ROS(任务:
起飞
,智能体:
RandomPolicySearch
):
roslaunch quad_controller_rl rl_controller.launch
这相当于明确指定任务和智能体类名称:
roslaunch quad_controller_rl rl_controller.launch task:=Takeoff agent:=RandomPolicySearch
现在运行模拟器可执行文件。它应该会启动并显示“Connected to ROS”,并且左下角有绿色的点。
跌落的四轴飞行器!
你将发现,在每个阶段开始时,四轴飞行器从很矮的高度掉了下来,落到地面上,然后机翼开始转动。因为智能体一开始遵守的是完全随机的策略,你将看到飞行器到处歪斜着飞行!幸运的话,它可能会升到一定的高度。
示例智能体
我们仔细研究下在
agents/policy_search.py
中定义的示例智能体
RandomPolicySearch
。从外部调用了两个方法:
-
__init__():初始化智能体,包括策略参数(随机设定)。它可以访问任务对象,因此可以检查状态空间和动作空间。 -
step():在每个时间步用一个新的状态(观察结果)向量和奖励进行调用。它预期会返回一个属于任务的动作空间的动作。
在这种情况下,
step()
方法只是累积每个时间步的奖励,并使用当前策略(
act()
方法)返回一个动作。你也可以在此处存储经验元组或执行其他运算。在每个阶段结束时,它都会调用
learn()
方法,该方法会尝试(随机地)更新策略以完善策略,然后通过调用
reset_episode_vars()
为下个阶段做准备。
这个随机策略搜索方法对该项目中的任务来说并不足够,但是你依然可以使用该智能体作为模板并定义你自己的智能体。
你的智能体
要实现你自己的智能体,请在
agents/
目录下创建一个新的 Python 文件。你可以根据你打算实现的算法/技巧命名它,例如
policy_gradients.py
。
现在创建一个继承自
BaseAgent
的类(或者你可以复制示例智能体中的部分,并根据需要加以修改)。例如,假设你要实现深度确定性策略梯度 (DDPG):
class DDPG(BaseAgent):
...
最后一个事项 - 为了运行智能体,你需要修改
agents/__init__.py
并在其中导入你的智能体类,例如:
from quad_controller_rl.agents.policy_gradients import DDPG
然后,在启动 ROS 时,你需要在命令行/终端上指定该类名称:
roslaunch quad_controller_rl rl_controller.launch agent:=DDPG
好了!现在你可以开始实现你的强化学习算法了!理想目标是训练智能体平稳地起飞。
四轴飞行器起飞了